[构造]Tautonym Puzzle
Tautonym Puzzle
Time Limit: 50 Sec Memory Limit: 256 MB
Description
定义一个序列贡献为1,当且仅当这个序列 由两个相同的串拼接而成,比如123123。
请构造一个序列,使得它子序列的贡献和为n。
要求序列长度<=200,权值<=100.
Input
一行一个n。
Output
第一行为长度len,表示你构造出的序列长度。
第二行为你构造出的序列。
Sample Input
7
Sample Output
4
1 1 1 1
HINT
n <= 1e12
Solution
构造题到恰好为n的。一般有两种方法:
1. 可以构造出2^n,并且每部分互不影响;
2. 有方法添加若干元素使得原有答案*2或+1。
我们先考虑第一种方法。
显然我们把 n 化为二进制。并且发现连续 x 个相同的数提供的贡献为2^(x-1)-1,并且若干个连续的不影响。
这样 s 需要1+2+……+log2(n)+(log2(n) * 2)(用于补1),极限是900。不能满足条件。
我们再考虑第二种方法。
s<=200,权值<=100。长度有5 * log2(n)可用,权值有2 * log2(n)可用。
先考虑这样一个问题:
<p1,p2,…,pk>已经是一个排列了,我们在后面加上**<1,2,…,k>之后的贡献是多少**。
显然,此时贡献为:<p1,p2,…,pk>的上升序列的个数。
那么我们把问题转化为:构造一个上升序列个数为n的排列。
假设我们原来的排列**<p1,p2,…,pk>已经x个上升序列了,现在填入k+1**。
显然,在前面填一个k+1贡献会变为:x+1。完成了**+1部分。
显然,在最后填一个k+1贡献会变为:x*2+1,这里多了一个+1**。怎么办呢?
显然一开始是0,经过3次操作:0*2+1=1,1*2+1=3,3*2+1=7;
假设一开始是1,经过3次操作:1*2=2,2*2=4,4*2=8。
发现我们如果将初值1的话,我们每次x*=2,最后再-1和原来的效果是一样的。这样就完成了*2部分。
最后用一个递归即可。
Code
1 |
|